#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <mysql.h>
#define ARRAY_SIZE 100
int top = -1;
int count = 0;
int k=1;
int array[] = { 0, 1, 2, 3, 4 };

int stack[ARRAY_SIZE];
int stack1[ARRAY_SIZE];
MYSQL *conn;
MYSQL_RES *res1;
MYSQL_RES *res2;
MYSQL_ROW row1;
void
dlevelpacking (int number, int size, int start, char (*attr)[10])
{
  if (number == 0)
    {
      char query[100] = "create table D select ";
      for (int k = 0; k <= top; k++)
	{
	  strcat (query, attr[stack[k]]);
	  if (k != top)
	    strcat (query, ",");
	}
      strcat (query, " from binary_table");
      printf ("query:%s\n", query);
      if (mysql_query (conn, query))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
	}
	      for (int n = 0; n <= top; n++)
        {
	char query5[100]="create table ";
          strcat (query5, attr[stack[n]]);
	strcat(query5," select distinct ");
	strcat(query5,attr[stack[n]]);
	strcat(query5," from binary_table");
printf ("%s\n",query5);
      if (mysql_query (conn, query5))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
	}
        }
char query6[100]="create table K select * from ";
	      for (int p= 0; p <= top; p++)
        {
strcat(query6,attr[stack[p]]);
if(p!=top) strcat(query6,",");
}	
printf("%s\n",query6);

      if (mysql_query (conn, query6))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
}
	      for (int q= 0; q <= top; q++)
        {
	    char query7[100]="drop table ";
		strcat(query7, attr[stack[q]]);
printf("%s\n",query7);
		      if (mysql_query (conn, query7))
        {
          printf ("%s\n", mysql_error (conn));
          exit (1);
        }
}
      char query2[100] = "insert into selected_tuples (";
      for (int m = 0; m <= top; m++)
	{
	  strcat (query2, attr[stack[m]]);
	  if (m != top)
	    strcat (query2, ",");
	  else
	    strcat (query2, ")");
	}
      strcat (query2, " select K.* from K left join D on K.");
      for (int h = 0; h <= top; h++)
	{
	  strcat (query2, attr[stack[h]]);
	  strcat (query2, "=D.");
	  strcat (query2, attr[stack[h]]);
	  if (h != top)
	    strcat (query2, " and K.");
	}
      strcat (query2, " where ");
      for (int l = 0; l <= top; l++)
	{
	  strcat (query2, "D.");
	  strcat (query2, attr[stack[l]]);
	  strcat (query2, " is NULL ");
	  if (l != top)
	    strcat (query2, " and ");
	}
      printf ("%s\n", query2);
for (int r=0; r < k ;r++){
      if (mysql_query (conn, query2))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
	}
}
      char query4[20] = "call drop_tables;";
      if (mysql_query (conn, query4))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
	}

      return;
    }
  for (int j = start; j < size; j++)
    {
      top++;
      stack[top] = array[j];
      dlevelpacking (number - 1, size, j + 1, attr);
      top--;
    }
}
void
neighborinsertion (int number, int size, int start, char (*attr)[10])
{
  if (number == 0)
    {
      char query[100] = "create table D select ";
      for (int k = 0; k <= top; k++)
	{
	  strcat (query, attr[stack1[k]]);
	  if (k != top)
	    strcat (query, ",");
	}
      strcat (query, " from binary_table");
      printf ("query:%s\n", query);
      if (mysql_query (conn, query))
	{
	  printf ("%s\n", mysql_error (conn));
	  exit (1);
	}
char query1[100]="create table N select ";

      for (int i = 0; i <= top; i++)
        {
          strcat (query1, attr[stack1[i]]);
            strcat (query1, ",");
}
strcat(query1,"count(*) from binary_table group by ");

      for (int i = 0; i <= top; i++)
        {
          strcat (query1, attr[stack1[i]]);
            if (i!=top) strcat (query1, ",");
}
	 strcat(query1," having count(*)>");
	 strcat(query1,"1");
	
printf("%s\n",query1);
           if (mysql_query (conn, query1))
        {
          printf ("%s\n", mysql_error (conn));
          exit (1);
        }
      char query3[100] = "insert into selected_tuples (";
      for (int m = 0; m <= top; m++)
	{
	  strcat (query3, attr[stack1[m]]);
	  if (m != top)
	    strcat (query3, ",");
	  else
	    strcat (query3, ") ");
	}
strcat(query3,"select D.* from D left join N on ");
      for (int j = 0; j <= top; j++)
        {
	strcat(query3,"N.");
          strcat (query3, attr[stack1[j]]);
	strcat(query3,"=D.");
          strcat (query3, attr[stack1[j]]);
            if (j!=top) strcat (query3, " and ");
}
strcat(query3," where ");
      for (int k = 0; k <= top; k++)
        {
strcat(query3,"N.");	
          strcat (query3, attr[stack1[k]]);
	strcat (query3," is NULL");
            if (k!=top) strcat (query3, " and ");
}
printf("%s\n",query3);
      if (mysql_query (conn, query3))
        {
          printf ("%s\n", mysql_error (conn));
          exit (1);
        }


      char query5[20] = "call drop_tables;";
      if (mysql_query (conn, query5))
        {
          printf ("%s\n", mysql_error (conn));
          exit (1);
        }
   
      return;
    }
  for (int j = start; j < size; j++)
    {
      top++;
      stack1[top] = array[j];
      neighborinsertion (number - 1, size, j + 1, attr);
      top--;
    }
}

int
main ()
{
  char query1[100] =
    "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name ='binary_table'";
  char query2[300] =
    "create table selected_tuples (atr1 int default 0,atr2 int default 0,atr3 int default 0,atr4 int default 0,atr5 int default 0)";
  char query3[300] =
    "drop table selected_tuples";

  char *user = "root";
  char *password = "password";
  char *server = "localhost";
  char *database = "privacy";
  char attrval[10][10];
  int k = 0;
  conn = mysql_init (NULL);
  if (!mysql_real_connect
      (conn, server, user, password, database, 0, NULL, 0))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }
  printf ("Query=%s\n", query1);
  if (mysql_query (conn, query1))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }
  res1 = mysql_store_result (conn);
  while (row1 = mysql_fetch_row (res1))
    {
      strcpy (attrval[k], row1[0]);
      k++;
    }
  if (mysql_query (conn, query2))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }

//  dlevelpacking (3, 5, 0, attrval);
top=-1;
neighborinsertion(3,5,0,attrval);
  if (mysql_query (conn, query3))
    {
      printf ("%s\n", mysql_error (conn));
      exit (1);
    }
  return 0;
}
